unit database_weapons;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
  Buttons, Spin, database_base, itemselectorframeunit, paramchangesframeunit,
  traitlist, fpjson;

type

  { TDatabaseWeaponsFrame }

  TDatabaseWeaponsFrame = class(TDatabaseBaseFrame)
    AnimationComboBox: TComboBox;
    AnimationLabel: TLabel;
    AnimationPanel: TPanel;
    DescriptionLabel: TLabel;
    DescriptionMemo: TMemo;
    DescriptionPanel: TPanel;
    GeneralSettingsFlowPanel: TFlowPanel;
    GeneralSettingsGroupBox: TGroupBox;
    NotesMemo: TMemo;
    NotesGroupBox: TGroupBox;
    WeaponTraitListFrame: TTraitListFrame;
    TraitsNotesSplitter: TSplitter;
    TraitsGroupBox: TGroupBox;
    IconIdLabel: TLabel;
    IconLabel: TLabel;
    IconPanel: TPanel;
    IconSpeedButton: TSpeedButton;
    MainContentScrollBox: TScrollBox;
    NameEdit: TEdit;
    NameLabel: TLabel;
    NamePanel: TPanel;
    MainAdditionalDataSplitter: TSplitter;
    AdditionalDataPanel: TPanel;
    WeaponParamChangesFrame: TParamChangesFrame;
    PriceLabel: TLabel;
    PricePanel: TPanel;
    PriceSpinEdit: TSpinEdit;
    SelectorContentSplitter: TSplitter;
    TypeComboBox: TComboBox;
    TypeLabel: TLabel;
    TypePanel: TPanel;
    WeaponSelectorFrame: TItemSelectorFrame;
    procedure AnimationComboBoxChange(Sender: TObject);
    procedure DescriptionMemoChange(Sender: TObject);
    procedure IconSpeedButtonClick(Sender: TObject);
    procedure Init; override;
    procedure NameEditChange(Sender: TObject);
    procedure NotesMemoChange(Sender: TObject);
    procedure PriceSpinEditChange(Sender: TObject);
    procedure TypeComboBoxChange(Sender: TObject);
  private
    IsLoading: Boolean;
    SelectedId: Integer;
    procedure ResizeMemo;
    procedure LoadGeneralSettings(Weapon: TJSONObject);
    procedure LoadParamChanges(Weapon: TJSONObject);
    procedure LoadAdditionalSettings(Weapon: TJSONObject);
    procedure LoadIcon(Weapon: TJSONObject);
    function GetSelectedWeapon: TJSONObject;
  public
    procedure LoadWeaponData(Id: Integer);
    procedure UpdateLanguage(Code: String); override;
  end;

resourcestring
  WeaponsHeader = 'Weapons';

implementation

uses
  comboboxhelper, constants, gamefont, languagehelper, globals, iconselection;

{$R *.lfm}

{ TDatabaseWeaponsFrame }

procedure TDatabaseWeaponsFrame.Init;
begin
  IsLoading := True;
  WeaponSelectorFrame.SetData(Db.Weapons, @Db.ResizeWeapons, @LoadWeaponData);
  WeaponSelectorFrame.Title := WeaponsHeader;
  WeaponSelectorFrame.JsonDataType := 'application/rpgmv-weapons';
  WeaponSelectorFrame.CreateElementCallback := @Db.CreateEmptyWeapon;
  FillDbArrayComboBox(AnimationComboBox, Db.Animations, AnimationNone);
  FillWeaponTypeComboBox(TypeComboBox, Db);
  WeaponParamChangesFrame.SetDatabase(Db);
  WeaponParamChangesFrame.AutoSize := True;
  WeaponTraitListFrame.SetDatabase(Db);

  ResizeMemo;

  LoadWeaponData(1);
end;

procedure TDatabaseWeaponsFrame.DescriptionMemoChange(Sender: TObject);
var
  Weapon: TJSONObject;
begin
  if IsLoading then
    Exit;

  Weapon := GetSelectedWeapon;
  if Weapon <> nil then
    Weapon.Strings['description'] := DescriptionMemo.Text;
end;

procedure TDatabaseWeaponsFrame.IconSpeedButtonClick(Sender: TObject);
var
  Weapon: TJSONObject;
  IconIndex: Integer = 0;
  IconIndexJson: TJSONNumber;
begin
  Weapon := GetSelectedWeapon;
  if (Weapon <> nil) and Weapon.Find('iconIndex', IconIndexJson) then
    IconIndex := IconIndexJson.AsInteger;

  if IconSelectionForm.ShowIconSelection(IconIndex) then begin
    Weapon.Integers['iconIndex'] := IconSelectionForm.SelectedIconId;
    LoadIcon(Weapon);
  end;
end;

procedure TDatabaseWeaponsFrame.AnimationComboBoxChange(Sender: TObject);
var
  Weapon: TJSONObject;
begin
  if IsLoading then
    Exit;

  Weapon := GetSelectedWeapon;
  if Weapon <> nil then
    Weapon.Integers['animationId'] := AnimationComboBox.ItemIndex;
end;

procedure TDatabaseWeaponsFrame.NameEditChange(Sender: TObject);
var
  Weapon: TJSONObject;
begin
  if IsLoading then
    Exit;

  Weapon := GetSelectedWeapon;
  if Weapon <> nil then begin
    Weapon.Strings['name'] := NameEdit.Text;
    WeaponSelectorFrame.RefreshSelectedName;
  end;
end;

procedure TDatabaseWeaponsFrame.NotesMemoChange(Sender: TObject);
var
  Weapon: TJSONObject;
begin
  if IsLoading then
    Exit;

  Weapon := GetSelectedWeapon;
  if Weapon <> nil then
    Weapon.Strings['note'] := NotesMemo.Text;
end;

procedure TDatabaseWeaponsFrame.PriceSpinEditChange(Sender: TObject);
var
  Weapon: TJSONObject;
begin
  if IsLoading then
    Exit;

  Weapon := GetSelectedWeapon;
  if Weapon <> nil then
    Weapon.Integers['price'] := PriceSpinEdit.Value
end;

procedure TDatabaseWeaponsFrame.TypeComboBoxChange(Sender: TObject);
var
  Weapon: TJSONObject;
begin
  if IsLoading then
    Exit;

  Weapon := GetSelectedWeapon;
  if Weapon <> nil then
    Weapon.Integers['wtypeId'] := TypeComboBox.ItemIndex + 1;
end;

procedure TDatabaseWeaponsFrame.ResizeMemo;
begin
  DescriptionMemo.Font.BeginUpdate;
  DescriptionMemo.Font.Name := GetMonospacedFontName;
  DescriptionMemo.Font.Size := GetMonospacedFontSize;
  DescriptionMemo.Font.EndUpdate;
  ResizeMemoForFont(DescriptionMemo, 55, 2);
end;

procedure TDatabaseWeaponsFrame.LoadGeneralSettings(Weapon: TJSONObject);
var
  WeaponName: String = '';
  Description: String = '';
  WeaponTypeId: Integer = 0;
  Price: Integer = 0;
  AnimationId: Integer = 0;
  NameJson, DescriptionJson: TJSONString;
  WeaponTypeIdJson, PriceJson, AnimationIdJson: TJSONNumber;
begin
  if (Weapon <> nil) and Weapon.Find('name', NameJson) then
    WeaponName := NameJson.AsString;
  NameEdit.Text := WeaponName;

  LoadIcon(Weapon);

  if (Weapon <> nil) and Weapon.Find('description', DescriptionJson) then
    Description := DescriptionJson.AsString;
  DescriptionMemo.Text := Description;

  if (Weapon <> nil) and Weapon.Find('wtypeId', WeaponTypeIdJson) then
    WeaponTypeId := WeaponTypeIdJson.AsInteger;
  TypeComboBox.ItemIndex := WeaponTypeId - 1;

  if (Weapon <> nil) and Weapon.Find('price', PriceJson) then
    Price := PriceJson.AsInteger;
  PriceSpinEdit.Value := Price;

  if (Weapon <> nil) and Weapon.Find('animationId', AnimationIdJson) then
    AnimationId := AnimationIdJson.AsInteger;
  AnimationComboBox.ItemIndex := AnimationId;
end;

procedure TDatabaseWeaponsFrame.LoadParamChanges(Weapon: TJSONObject);
var
  Params: TJSONArray;
begin
  if (Weapon <> nil) and Weapon.Find('params', Params) then
    WeaponParamChangesFrame.SetEditedParams(Params)
  else
    WeaponParamChangesFrame.SetEditedParams(nil);
end;

procedure TDatabaseWeaponsFrame.LoadAdditionalSettings(Weapon: TJSONObject);
var
  Notes: String = '';
  NotesJson: TJSONString;
  Traits: TJSONArray;
begin
  if (Weapon <> nil) and Weapon.Find('traits', Traits) then
    WeaponTraitListFrame.SetTraitList(Traits)
  else
    WeaponTraitListFrame.SetTraitList(nil);

  if (Weapon <> nil) and Weapon.Find('note', NotesJson) then
    Notes := NotesJson.AsString;
  NotesMemo.Text := Notes;
end;

procedure TDatabaseWeaponsFrame.LoadIcon(Weapon: TJSONObject);
var
  IconId: Integer = 0;
  IconIdJson: TJSONNumber;
  IconBitmap: TBitmap;
begin
  if (Weapon <> nil) and Weapon.Find('iconIndex', IconIdJson) then
    IconId := IconIdJson.AsInteger;

  IconIdLabel.Caption := IntToStr(IconId);
  if IconId <> 0 then begin
    IconBitmap := Game.GetIcon(IconId);
    IconSpeedButton.Glyph.Assign(IconBitmap);
    IconBitmap.Free;
  end else
    IconSpeedButton.Glyph.Clear;
end;

function TDatabaseWeaponsFrame.GetSelectedWeapon: TJSONObject;
begin
  GetSelectedWeapon := nil;
  if Db.Weapons <> nil then
    if (SelectedId >= 1) and (SelectedId <= Db.Weapons.Count -1) then
      GetSelectedWeapon := Db.Weapons.Objects[SelectedId];
end;

procedure TDatabaseWeaponsFrame.LoadWeaponData(Id: Integer);
var
  Weapon: TJSONObject;
begin
  IsLoading := True;
  SelectedId := Id;

  Weapon := GetSelectedWeapon;
  LoadGeneralSettings(Weapon);
  LoadParamChanges(Weapon);
  LoadAdditionalSettings(Weapon);

  IsLoading := False;
end;

procedure TDatabaseWeaponsFrame.UpdateLanguage(Code: String);
begin
  inherited UpdateLanguage(Code);
  if IsLanguageRtl(Code) then begin
    GeneralSettingsFlowPanel.FlowStyle := fsRightLeftTopBottom;
  end else begin
    GeneralSettingsFlowPanel.FlowStyle := fsLeftRightTopBottom;
  end;
  WeaponParamChangesFrame.UpdateLanguage(Code);
end;

end.

